use std::{env,fs};
use pest::Parser;
use pest_derive::Parser;

// #[derive(Parser)]
// #[grammar = "grammar.pest"]
// struct IdentParser;

// // // 派生 Parser trait 并指定 grammar 文件
#[derive(Parser)]
#[grammar = "lexer.pest"] // 指向你的 .pest 文件
struct SysYLexer;

fn main(){
    let args: Vec<String> = env::args().collect();
    if args.len() < 2{
        eprintln!("Usage: {} <filename>",args[0]);
        std::process::exit(1);
    }

    let filename = &args[1];
    let input = fs::read_to_string(&filename).expect("Failed to read file");

    tokenize(&input);

}

fn tokenize(input: &str) {
    // TODO: error
    let pairs = SysYLexer::parse(Rule::token_list, input)
        .unwrap_or_else(|e| panic!("Parse error: {}", e));

    for pair in pairs {
        for inner in pair.into_inner() {
            if inner.as_rule() == Rule::WS { continue; }
            let span = inner.as_span();
            let start = span.start();
            let line = 1 + input[..start].chars().filter(|&c| c == '\n').count();

            if inner.as_rule() == Rule::INTEGER_CONST {
                let raw = inner.as_str();
                let value = if raw.starts_with("0x") || raw.starts_with("0X") {
                    u64::from_str_radix(&raw[2..], 16).unwrap()
                } else if raw.starts_with('0') && raw.len() > 1 {
                    u64::from_str_radix(&raw[1..], 8).unwrap()
                } else {
                    raw.parse::<u64>().unwrap()
                };
                eprintln!("{:?} {} at Line {}.", inner.as_rule(), value, line);
            } else {
                eprintln!("{:?} {} at Line {}.", inner.as_rule(), inner.as_str().trim(), line);
            }
        }
    }
}